package controller

import (
	"html/template"
	"net/http"
	"strconv"
	"web08_35_tushu/dao"
	"web08_35_tushu/model"
	"web08_35_tushu/utils"
)

//AddBook2Cart 添加图书到购物车
func AddBook2Cart(w http.ResponseWriter, r *http.Request) {
	//先获取传过来的图书ID，这就是要添加的图书的ID
	bookID := r.FormValue("bookId")
	//根据图书ID获取图书信息
	book, _ := dao.GetBookByID(bookID)
	//判断是否登录
	flag, session := dao.IsLogin(r)
	if !flag {
		w.Write([]byte("请登录"))
		return
	}
	//获取用户ID
	userID := session.UserID
	//通过用户ID查购物车，通过这个判断用户是否有购物车
	cart, _ := dao.GetCartByUserID(userID)
	if cart != nil {
		//当前用户已经有购物车，判断是否存在该图书购物项
		iscartItem, _ := dao.GetCartItemByBookIDAndCartID(bookID, cart.CartID)
		if iscartItem != nil {
			//不为空，说明有该图书购物项，将该购物项里的count加1就行
			//这个分支需要更新购物项和购物车
			//1.获取购物车所有购物项
			cts := cart.CartItems
			//2.遍历所有购物项，找出对应的购物项并将其数量加1
			for _, v := range cts {
				if v.Book.ID == iscartItem.Book.ID {
					//因为是指针所以可以直接操作
					v.Count = v.Count + 1
					//更新购物项中的数量和金额
					dao.UpdateBookCountAndAmount(v.Count, v.GetAmount(), v.Book.ID, cart.CartID)
				}
			}
		} else {
			//为空，说明没有该图书购物项，创建一个并加到数据库里
			//到这个分支的话只需要更新购物车就行了，购物项是直接添加的
			cartItem := &model.CartItem{
				Book:   book,
				Count:  1,
				CartID: cart.CartID,
			}
			//把新添加的购物项加入购物车的购物项切片里
			cart.CartItems = append(cart.CartItems, cartItem)
			//这里先添加购物项，购物车的更新在下面统一进行
			dao.AddCartItem(cartItem)

		}
		//上面两个完成后都需要更新购物车，所以购物车写在下面
		dao.UpdateCart(cart)
	} else {
		//当前用户没有购物车，没有就创建购物车
		//1.生成购物车ID
		cartID := utils.CreateUUID()
		cart := &model.Cart{
			CartID: cartID,
			UserID: userID,
		}
		//2.创建购物车里的购物项
		//声明个购物项切片用来装单个购物项
		var cartItems []*model.CartItem
		//声明单个购物项
		cartItem := &model.CartItem{
			Book:   book,
			Count:  1,
			CartID: cartID,
		}
		//3.将单个购物项添加到切片里
		cartItems = append(cartItems, cartItem)
		//4.将切片装进购物车里
		cart.CartItems = cartItems
		//5.把组装好的购物车保存到数据库里
		dao.AddCart(cart)
	}
	w.Write([]byte("您刚刚将" + book.Title + "加入购物车"))
}

//GetCartInfo 前往购物车页面
func GetCartInfo(w http.ResponseWriter, r *http.Request) {
	//判断是否登录并获取session信息
	flag, session := dao.IsLogin(r)
	//如果没登录就跳转到登录页面
	if !flag {
		w.Header().Set("Location", "/login")
		w.WriteHeader(302)
		return
	}
	//用户ID查购物车
	userID := session.UserID
	cart, _ := dao.GetCartByUserID(userID)
	//判断是否有购物车
	if cart != nil {
		//这里是把用户名给购物车，方便页面那边显示欢迎xxx
		cart.UserName = session.UserName
		t := template.Must(template.ParseFiles("pages/cart/cart.html"))
		t.Execute(w, cart)
	} else {
		//当前用户没有购物车，没有就创建购物车
		cartID := utils.CreateUUID()
		cart2 := &model.Cart{
			CartID: cartID,
			UserID: userID,
		}
		dao.AddCart(cart2)
		//这里是把用户名给购物车，方便页面那边显示欢迎xxx
		cart2.UserName = session.UserName
		t := template.Must(template.ParseFiles("pages/cart/cart.html"))
		t.Execute(w, cart2)
	}
}

//DeleteCart 清空购物车
func DeleteCart(w http.ResponseWriter, r *http.Request) {
	//判断是否登录并获取session信息
	flag, session := dao.IsLogin(r)
	//如果没登录就跳转到登录页面
	if !flag {
		w.Header().Set("Location", "/login")
		w.WriteHeader(302)
		return
	}
	//用户ID查购物车
	userID := session.UserID
	cart, _ := dao.GetCartByUserID(userID)
	//根据购物车ID删除购物车
	dao.DeleteCartByCartID(cart.CartID)
	//删除完后重新回到该页面，相当于刷新了一下
	w.Header().Set("Location", "/getCartInfo")
	w.WriteHeader(302)
}

//DeleteCartItem 删除单个购物项
func DeleteCartItem(w http.ResponseWriter, r *http.Request) {
	//先获取图书ID
	cartItemID := r.FormValue("cartItemId")
	//判断是否登录并获取session信息
	flag, session := dao.IsLogin(r)
	//如果没登录就跳转到登录页面
	if !flag {
		w.Header().Set("Location", "/login")
		w.WriteHeader(302)
		return
	}
	//获取用户ID方便查询购物车
	userID := session.UserID
	//查询购物车，这步是为了获取购物车ID
	cart, _ := dao.GetCartByUserID(userID)
	//删除指定购物项
	dao.DeleteCartItemByID(cartItemID, cart.CartID)
	//再查询一遍，此时里面已经没有那个购物项了，剩下只需要改下购物车信息就行了
	cart2, _ := dao.GetCartByUserID(userID)
	//更新一下，这里更新函数是重新计算数值，所以直接用就行
	dao.UpdateCart(cart2)
	//删除完后重新回到该页面，相当于刷新了一下
	w.Header().Set("Location", "/getCartInfo")
	w.WriteHeader(302)

}

//下面这个原始的没有ajax跳转的用户购物项更新

//UpdateCartItem 更新单个购物项，用于用户购物车页面
func UpdateCartItem(w http.ResponseWriter, r *http.Request) {
	//先获取图书ID和数量
	bookID := r.FormValue("bookId")
	ibookCount := r.FormValue("bookCount")
	bookCount, _ := strconv.ParseInt(ibookCount, 10, 64)
	//判断是否登录并获取session信息
	flag, session := dao.IsLogin(r)
	//如果没登录就跳转到登录页面
	if !flag {
		w.Header().Set("Location", "/login")
		w.WriteHeader(302)
		return
	}
	//获取用户ID方便查询购物车
	userID := session.UserID
	//查询购物车，这步是为了获取购物车ID
	cart, _ := dao.GetCartByUserID(userID)
	//获取要更改的购物项
	cartItem, _ := dao.GetCartItemByBookIDAndCartID(bookID, cart.CartID)
	//把数量更新了，总价格在dao更新函数里用了GetAmount()直接计算
	cartItem.Count = bookCount
	//更新指定购物项
	dao.UpdateBookCount(cartItem, cart.CartID)
	//再查询一遍，此时里面那个购物项已经改了，剩下只需要改下购物车信息就行了
	cart2, _ := dao.GetCartByUserID(userID)
	//更新一下，这里更新函数是重新计算数值，所以直接用就行
	dao.UpdateCart(cart2)
	//删除完后重新回到该页面，相当于刷新了一下
	w.Header().Set("Location", "/getCartInfo")
	w.WriteHeader(302)

}

// //UpdateCartItem 更新单个购物项，这是ajax的
// func UpdateCartItem(w http.ResponseWriter, r *http.Request) {
// 	//获取要更新的购物项的id
// 	cartItemID := r.FormValue("cartItemId")
// 	//将购物项的id转换为int64
// 	iCartItemID, _ := strconv.ParseInt(cartItemID, 10, 64)
// 	//获取用户输入的图书的数量
// 	bookCount := r.FormValue("bookCount")
// 	iBookCount, _ := strconv.ParseInt(bookCount, 10, 64)
// 	//获取session
// 	_, session := dao.IsLogin(r)
// 	//获取用户的id
// 	userID := session.UserID
// 	//获取该用户的购物车
// 	cart, _ := dao.GetCartByUserID(userID)
// 	//获取购物车中的所有的购物项
// 	cartItems := cart.CartItems
// 	//遍历得到每一个购物项
// 	for _, v := range cartItems {
// 		//寻找要更新的购物项
// 		if v.CartItemID == iCartItemID {
// 			//这个就是我们要更新的购物项
// 			//将当前购物项中的图书的数量设置为用户输入的值
// 			v.Count = iBookCount
// 			//更新数据库中该购物项的图书的数量和金额小计
// 			dao.UpdateBookCount(v)
// 		}
// 	}
// 	//更新购物车中的图书的总数量和总金额
// 	dao.UpdateCart(cart)
// 	//调用获取购物项信息的函数再次查询购物车信息
// 	cart, _ = dao.GetCartByUserID(userID)
// 	// GetCartInfo(w, r)
// 	//获取购物车中图书的总数量
// 	totalCount := cart.TotalCount
// 	//获取购物车中图书的总金额
// 	totalAmount := cart.TotalAmount
// 	var amount float64
// 	//获取购物车中更新的购物项中的金额小计
// 	cIs := cart.CartItems
// 	for _, v := range cIs {
// 		if iCartItemID == v.CartItemID {
// 			//这个就是我们寻找的购物项，此时获取当前购物项中的金额小计
// 			amount = v.Amount
// 		}
// 	}
// 	//创建Data结构
// 	data := model.Data{  //这个需要创建个结构体，结构体对象可以直接转换为json
// 		Amount:      amount,
// 		TotalAmount: totalAmount,
// 		TotalCount:  totalCount,
// 	}
// 	//将data转换为json字符串
// 	json, _ := json.Marshal(data)
// 	//响应到浏览器
// 	w.Write(json)
// }
